package com.yiduo.outpost.gateway.config;

import cn.hutool.core.net.NetUtil;
import cn.hutool.core.util.ArrayUtil;
import com.alibaba.csp.sentinel.adapter.gateway.common.param.RequestItemParser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpCookie;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.server.ServerWebExchange;

import java.net.InetSocketAddress;
import java.util.Optional;
@Slf4j
public class ServerWebExchangeItemParser implements RequestItemParser<ServerWebExchange> {
    @Override
    public String getPath(ServerWebExchange exchange) {
        return exchange.getRequest().getPath().value();
    }

    @Override
    public String getRemoteAddress(ServerWebExchange exchange) {
        return getClientIP(exchange.getRequest());
    }

    @Override
    public String getHeader(ServerWebExchange exchange, String key) {
        return exchange.getRequest().getHeaders().getFirst(key);
    }

    @Override
    public String getUrlParam(ServerWebExchange exchange, String paramName) {
        return exchange.getRequest().getQueryParams().getFirst(paramName);
    }

    @Override
    public String getCookieValue(ServerWebExchange exchange, String cookieName) {
        return Optional.ofNullable(exchange.getRequest().getCookies().getFirst(cookieName))
                .map(HttpCookie::getValue)
                .orElse(null);
    }
    public static String getClientIP(ServerHttpRequest request, String... otherHeaderNames) {
        try{
            String[] headers = { "X-Forwarded-For","x-forwarded-for", "X-Real-IP", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR" };
            if (ArrayUtil.isNotEmpty(otherHeaderNames)) {
                headers = ArrayUtil.addAll(headers, otherHeaderNames);
            }
            String clientIPByHeader = getClientIPByHeader(request, headers);
            log.debug("当前访问 clientIp: {}",clientIPByHeader);
            return clientIPByHeader;
        }catch (Exception e){
            log.error("当前访问 clientIp 解析异常 ",e);
        }
        return null;
        //
    }

    public static String getClientIPByHeader(ServerHttpRequest request, String... headerNames) {
        String ip;
        for (String header : headerNames) {
            ip = request.getHeaders().getFirst(header);
            if (false == NetUtil.isUnknown(ip)) {
                return NetUtil.getMultistageReverseProxyIp(ip);
            }
        }
        InetSocketAddress remoteAddress = request.getRemoteAddress();
        if (remoteAddress == null) {
            return null;
        }
        ip = remoteAddress.getAddress().getHostAddress();
        return NetUtil.getMultistageReverseProxyIp(ip);
    }
}
